from typing import Optional, List, Dict

from pydantic import BaseModel, root_validator

from loggers.configs import logger, log_verbose
from load_online_model.model_config import TEMPERATURE


# 在线API配置参数，未提供的值会自动从model_config.ONLINE_LLM_MODEL中读取
class ApiConfigParams(BaseModel):
    api_base_url: Optional[str] = None
    api_proxy: Optional[str] = None
    api_key: Optional[str] = None
    secret_key: Optional[str] = None
    group_id: Optional[str] = None  # for minimax
    is_pro: bool = False  # for minimax

    APPID: Optional[str] = None  # for xinghuo
    APISecret: Optional[str] = None  # for xinghuo
    is_v2: bool = False  # for xinghuo

    worker_name: Optional[str] = None

    class Config:
        extra = "allow"

    @root_validator(pre=True)
    def validate_config(cls, v: Dict) -> Dict:
        if config := get_model_worker_config(v.get("worker_name")):
            for n in cls.__fields__:
                if n in config:
                    v[n] = config[n]
        return v

    def load_config(self, worker_name: str):
        self.worker_name = worker_name
        if config := get_model_worker_config(worker_name):
            for n in self.__fields__:
                if n in config:
                    setattr(self, n, config[n])
        return self


# 在embedding模型的访问，需要的参数
class ApiEmbeddingsParams(ApiConfigParams):
    texts: List[str]
    embed_model: Optional[str] = None
    to_query: bool = False  # for minimax


# 模型配置参数
class ApiModelParams(ApiConfigParams):
    version: Optional[str] = None
    version_url: Optional[str] = None
    api_version: Optional[str] = None  # for azure
    deployment_name: Optional[str] = None  # for azure
    resource_name: Optional[str] = None  # for azure

    temperature: float = TEMPERATURE
    max_tokens: Optional[int] = None
    top_p: Optional[float] = 1.0


# 加载model worker的配置项;
# 优先级:FSCHAT_MODEL_WORKERS[model_name] > ONLINE_LLM_MODEL[model_name] > FSCHAT_MODEL_WORKERS["default"]
def get_model_worker_config(model_name: str = None) -> dict:
    from model_config import ONLINE_LLM_MODEL
    import model_works

    config = ONLINE_LLM_MODEL.get(model_name, {}).copy()

    if model_name in ONLINE_LLM_MODEL:
        config["online_api"] = True
        if provider := config.get("provider"):
            try:
                config["worker_class"] = getattr(model_works, provider)
            except Exception as e:
                msg = f"在线模型 ‘{model_name}’ 的provider没有正确配置"
                logger.error(f'{e.__class__.__name__}: {msg}',
                             exc_info=e if log_verbose else None)
    return config
